

use cache::{ExecutorInfo, FlowCache, SaveType};
use conf::{get_managers, get_user_from_conf};
use history::get_user_from_history;
use running::get_user_from_running;
use shq_common::prelude::TaskStatus;

use crate::config::{get_workflow_config, NoExecutorTactics, Workflow};
pub(crate) mod cache;
pub(crate) mod conf;
mod history;
mod running;
pub(crate) async fn get_executor(run_id: u64, step_id: u8, tx: Option<&mut sqlx::Transaction<'_, sqlx::MySql>>) -> anyhow::Result<Vec<ExecutorInfo>> {
    let mut fuc = FlowCache::from(run_id)?;
    let fi = fuc.get_flow_info().await?;
    let mut res = if fi.state == 1 {
        get_user_from_history(run_id, step_id, tx).await?
    } else {
        get_user_from_running(run_id, step_id, tx).await?
    };
    if res.is_empty() {
        res=get_user_from_conf(run_id, fi.wfid, fi.version, step_id).await?
    }
    if res.is_empty() {
        let conf = get_workflow_config(fi.wfid, fi.version).ok_or(anyhow::anyhow!(
            "WFID:{},version:{}在配置中不存在",
            fi.wfid, fi.version
        ))?;
        let step = conf.get_step(step_id).ok_or(anyhow::anyhow!(
            "在配置WFID:{}中不存在step:{}",
            fi.wfid,
            step_id
        ))?;
        if step.no_executor_tractics==NoExecutorTactics::Manager {
            let mas=get_managers(fi.wfid, fi.version).await?;
            res=mas.into_iter().map(|id| ExecutorInfo {
                user_id: id,
                task_state: TaskStatus::None,
                start_time: None,
                submit_time: None,
                feed_back: None,
                save_type: SaveType::None,
            }).collect()
        }
    }
    fuc.set_step_users(step_id, &res)?;
    Ok(res)
}
pub(crate) async fn is_can_create_flow(conf: &Workflow, user_id: u32) -> anyhow::Result<bool> {
    for e in conf.steps[0].executors.iter() {
        let is_can = match e.r#type {
            crate::config::ExecutorType::Role => {
                let mut is_can = false;
                for rid in e.ids.iter() {
                    is_can = shq_auth::user_has_role(user_id,*rid).await?;
                    if is_can {
                        break;
                    }
                }
                is_can
            }
            crate::config::ExecutorType::User => e.ids.contains(&user_id),
            crate::config::ExecutorType::Func => false,
        };
        if is_can {
            return Ok(true);
        }
    }
    Ok(false)
}
